package com.ssl.rms.shiro.realm;

import com.ssl.rms.entity.User;
import com.ssl.rms.service.UserService;
import com.ssl.rms.shiro.UsernamePasswordToken;
import com.ssl.rms.shiro.filters.FormAuthenticationFilter;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.web.servlet.NameableFilter;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;

/**
 * 描述：realm
 *
 * @author ssl
 * @create 2018/02/06 17:12
 */
public class UserRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;

    /**
     * 授权查询回调函数:只有需要验证权限时才会调用,进行鉴权但缓存中无用户的授权信息时调用.在配有缓存的情况下，只加载一次
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("UserRealm.doGetAuthorizationInfo");
        return new SimpleAuthorizationInfo();
    }

    /**
     * 认证回调函数:登录时调用
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        User user = null;
        NameableFilter loginFilter = token.getLoginFilter();
        if (FormAuthenticationFilter.LOGIN_FILTER_NAME.equals(loginFilter.toString())) {
            /** formauth过滤器验证 */
            user = userService.findByUserName(token.getUsername());
            if (null == user) {
                throw new UnknownAccountException();
            }
            /** 不对密码进行加密后匹配 */
            // setCredentialsMatcher(new AllowAllCredentialsMatcher());
            return new SimpleAuthenticationInfo(new Principal(user), user.getPassword(), ByteSource.Util.bytes
                    (user.getSalt()), getName());
        }
        return null;
    }

    /**
     * 自定义授权用户信息，可扩展
     */
    public static class Principal implements Serializable {
        private static final long serialVersionUID = 1L;

        private Long id;
        private String userName;
        private Boolean isRoot;

        public Principal(User user) {
            this.id = user.getId();
            this.userName = user.getUserName();
            this.isRoot = user.getIsRoot();
        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public Boolean getRoot() {
            return isRoot;
        }

        public void setRoot(Boolean root) {
            isRoot = root;
        }
    }

    /**
     * 更新用户授权信息缓存.
     */
    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }

    /**
     * 更新用户信息缓存.
     */
    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }

    /**
     * 清除用户授权信息缓存.
     */
    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    /**
     * 清除用户信息缓存.
     */
    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    /**
     * 清空所有缓存
     */
    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }

    /**
     * 清空所有认证缓存
     */
    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }

}
